package com.w.picture.aop;

import com.w.picture.annotation.RoleCheck;
import com.w.picture.exception.BusinessException;
import com.w.picture.exception.ErrorCode;
import com.w.picture.mode.entity.User;
import com.w.picture.mode.enums.UserRoleEnum;
import com.w.picture.service.UserService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @author wzp
 * @since 2024/12/15
 */
@Aspect
@Component
public class RoleCheckAspect {

    @Resource
    private UserService userService;


    @Around("@annotation(roleCheck)")
    public Object checkRole(ProceedingJoinPoint proceedingJoinPoint, RoleCheck roleCheck) throws Throwable {
        // 如果没有设置角色，或者角色为空，直接执行方法（所有人可以访问）
        if (roleCheck == null || roleCheck.value().isEmpty()) {
            return proceedingJoinPoint.proceed();
        }

        // 获取当前用户
        User loginUser = getLoginUser();

        // 检查用户是否登录以及是否有权限访问
        validateUserPermissions(loginUser, roleCheck);

        // 继续执行目标方法
        return proceedingJoinPoint.proceed();
    }


    private User getLoginUser() {
        // 通过spring mvc 获取request
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();
        return userService.getLoginUser(httpServletRequest);
    }

    private void validateUserPermissions(User loginUser, RoleCheck roleCheck) {
        // Admin 角色可以访问所有资源
        boolean isAdmin = isAdminRole(loginUser);
        boolean hasRequiredRole = loginUser != null &&
                !roleCheck.value().isEmpty() &&
                roleCheck.value().equals(loginUser.getUserRole());

        // 如果不是管理员，并且没有指定角色，或者指定的角色与用户的角色不匹配，则抛出异常
        if (!isAdmin && !hasRequiredRole) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
    }

    private boolean isAdminRole(User user) {
        return user != null && UserRoleEnum.ADMIN.getValue().equals(user.getUserRole());
    }
}
